/***************************************************************************
 *   Copyright (C) 2010 by Oleg Goncharov  *
 *   $EMAIL$                           *                          
 *                                                                         *
 *   This file is part of ChessVision.                                     *
 *                                                                         *
 *   ChessVision is free software; you can redistribute it and/or modify   *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef CIMAGEOBJECT_H
#define CIMAGEOBJECT_H

#include <opencv/cv.h>

#define OBJECT_MAX_MOMENT 3

#include "geomtypes.h"

/**
Объект на изображении.

	@author Goncharov Oleg <goncharovoi@yandex.ru>
*/
class CImageObject {
protected:
	CvRect rect;
	IplImage * img;
	CvMat * mask;
	
	double area;
	double * perimeter;
	bool m_is_calulated;
	CvMoments m;
	
	CvScalar * avg_color;
	
protected:
	void CalcMoments() {
		if (!m_is_calulated) cvMoments(mask, &m, 1);
	}
	void Clear();
public:
	CImageObject(IplImage * img, IplImage * seg, const CvConnectedComp& obj);
	CImageObject(IplImage * src, CvMat * _mask, const CvConnectedComp& obj);
	CImageObject(const CImageObject& obj);
	~CImageObject() { Clear(); }
	
	SRect GetRect() { return SRect(rect); }
	const CvRect& GetCvRect() { return rect; }
	
	double Area() const { return area; }
	double Perimeter();
	double Compactness() { 
		if (! perimeter) Perimeter(); 
		return (*perimeter)*(*perimeter)/area; 
	}
	CvMoments * GetMoments() { 
		if (! m_is_calulated) CalcMoments(); 
		return &m; 
	}
	cv::Point2f CenterOfMass() {
		if (!m_is_calulated) CalcMoments();
		double x = rect.x + cvGetSpatialMoment(&m, 1, 0)/area;
		double y = rect.y + cvGetSpatialMoment(&m, 0, 1)/area;
		//return cv::Point2f(rect.x + cvGetSpatialMoment(&m, 1, 0)/cvGetSpatialMoment(&m, 0, 0), rect.y + cvGetSpatialMoment(&m, 0, 1)/cvGetSpatialMoment(&m, 0, 0));
		return cv::Point2f(x, y);
	}
	double Elongation();
	CvScalar AvgColor();
	
	bool Merge(CImageObject& o, int distance = 1, bool force = false); 
	
	void Draw(IplImage * img);
};

#endif
